home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / mint104s.zoo / mint.src / bios.c < prev    next >
C/C++ Source or Header  |  1993-03-08  |  22KB  |  951 lines

  1. /*
  2. Copyright 1990,1991,1992 Eric R. Smith.
  3. Copyright 1992,1993 Atari Corporation.
  4. All rights reserved.
  5. */
  6.  
  7. /*
  8.  * BIOS replacement routines
  9.  */
  10.  
  11. #include "mint.h"
  12. #include "xbra.h"
  13.  
  14. #define UNDEF 0        /* should match definition in tty.c */
  15.  
  16. /* some key definitions */
  17. #define CTRLALT 0xc
  18. #define DEL 0x53    /* scan code of delete key */
  19. #define UNDO 0x61    /* scan code of undo key */
  20.  
  21. /* BIOS device definitions */
  22. #define CONSDEV 2
  23. #define AUXDEV 1
  24.  
  25. /* BIOS devices 0..MAX_BHANDLE-1 can be redirected to GEMDOS files */
  26. #define MAX_BHANDLE    4
  27.  
  28. /* BIOS redirection maps */
  29. const short binput[MAX_BHANDLE] = { -3, -2, -1, -4 };
  30. const short boutput[MAX_BHANDLE] = { -3, -2, -1, -5 };
  31.  
  32. /* tty structures for the BIOS devices -- see biosfs.c */
  33. extern struct tty con_tty, aux_tty, midi_tty;
  34.  
  35. extern int tosvers;    /* from main.c */
  36. char *kbshft;        /* set in main.c */
  37.  
  38. /* some BIOS vectors; note that the routines at these vectors may do nasty
  39.  * things to registers!
  40.  */
  41.  
  42. #define RWABS *((long *)0x476L)
  43. #define MEDIACH *((long *)0x47eL)
  44. #define GETBPB *((long *)0x472L)
  45.  
  46. #define is_falcon ((mch & 0xffff0000L) == 0x00030000L)
  47.  
  48. #if 1
  49. /* these are supposed to be tables holding the addresses of the
  50.  * first 8 BconXXX functions, but in fact only the first 5 are
  51.  * placed here (and device 5 only has Bconout implemented; 
  52.  * we don't use that device (raw console) anyway).
  53.  */
  54.  
  55. #define xconstat ((long *)0x51eL)
  56. #define xconin     ((long *)0x53eL)
  57. #define xcostat ((long *)0x55eL)
  58. #define xconout    ((long *)0x57eL)
  59.  
  60. #define BCOSTAT(dev) \
  61.     ((tosvers >= 0x0102 && (unsigned)dev <= 4) ? \
  62.        (int)callout1(xcostat[dev], dev) : Bcostat(dev))
  63. #define BCONOUT(dev, c) \
  64.     ((tosvers >= 0x0102 && (unsigned)dev <= 4) ? \
  65.        callout2(xconout[dev], dev, c) : Bconout(dev, c))
  66. #define BCONSTAT(dev) \
  67.     ((tosvers >= 0x0102 && (unsigned)dev <= 4) ? \
  68.        (int)callout1(xconstat[dev], dev) : Bconstat(dev))
  69. #define BCONIN(dev) \
  70.     ((tosvers >= 0x0102 && (unsigned)dev <= 4) ? \
  71.        callout1(xconin[dev], dev) : Bconin(dev))
  72. #else
  73. #define BCOSTAT(dev) Bcostat(dev)
  74. #define BCONOUT(dev,c) Bconout(dev,c)
  75. #define BCONSTAT(dev) Bconstat(dev)
  76. #define BCONIN(dev) Bconin(dev)
  77. #endif
  78.  
  79. /* variables for monitoring the keyboard */
  80. IOREC_T    *keyrec;        /* keyboard i/o record pointer */
  81. short    kintr = 0;        /* keyboard interrupt pending (see intr.s) */
  82.  
  83. /* Getmpb is not allowed under MiNT */
  84.  
  85. long ARGS_ON_STACK
  86. getmpb(ptr)
  87.     void *ptr;
  88. {
  89.     UNUSED(ptr);
  90.  
  91.     DEBUG(("failed call to Getmpb"));
  92.     return -1;
  93. }
  94.  
  95.  
  96. /*
  97.  * Note that BIOS handles 0 - MAX_BHANDLE now reference file handles;
  98.  * to get the physical devices, go through u:\dev\
  99.  *
  100.  * A note on translation: all of the bco[n]XXX functions have a "u"
  101.  * variant that is actually what the user calls. For example,
  102.  * ubconstat is the function that gets control after the user does
  103.  * a Bconstat. It figures out what device or file handle is
  104.  * appropriate. Typically, it will be a biosfs file handle; a
  105.  * request is sent to biosfs, and biosfs in turn figures out
  106.  * the "real" device and calls bconstat.
  107.  */
  108.  
  109. /*
  110.  * WARNING: syscall.spp assumes that ubconstat never blocks.
  111.  */
  112. long ARGS_ON_STACK
  113. ubconstat(dev)
  114. int dev;
  115. {
  116.     if (dev < MAX_BHANDLE) {
  117.         FILEPTR *f = curproc->handle[binput[dev]];
  118.         return file_instat(f) ? -1 : 0;
  119.     }
  120.     else
  121.         return bconstat(dev);
  122. }
  123.  
  124. long
  125. bconstat(dev)
  126. int dev;
  127. {
  128.     if (dev == CONSDEV) {
  129.         if (checkkeys()) return 0;
  130.         return (keyrec->head != keyrec->tail) ? -1 : 0;
  131.     }
  132.     if (dev == AUXDEV && has_bconmap)
  133.         dev = curproc->bconmap;
  134.  
  135. /* compensate for a bug in the Falcon BIOS */
  136.     if (dev == 7 && is_falcon)
  137.         return Bconstat(1);
  138.  
  139.     return BCONSTAT(dev);
  140. }
  141.  
  142. /* bconin: input a character */
  143. /*
  144.  * WARNING: syscall.spp assumes that ubconin never
  145.  * blocks if ubconstat returns non-zero.
  146.  */
  147. long ARGS_ON_STACK
  148. ubconin(dev)
  149. int dev;
  150. {
  151.     if (dev < MAX_BHANDLE) {
  152.         FILEPTR *f = curproc->handle[binput[dev]];
  153.         return file_getchar(f, RAW);
  154.     }
  155.     else
  156.         return bconin(dev);
  157. }
  158.  
  159. long
  160. bconin(dev)
  161. int dev;
  162. {
  163.     IOREC_T *k;
  164.     long r;
  165.     short h;
  166.  
  167.     if (dev == CONSDEV) {
  168.         k = keyrec;
  169. again:
  170.         while (k->tail == k->head) {
  171.             yield();
  172.         }
  173.  
  174.         if (checkkeys()) goto again;
  175.  
  176.         h = k->head + 4;
  177.         if (h >= k->buflen)
  178.             h = 0;
  179.         r = *((long *)(k->bufaddr + h));
  180.         k->head = h;
  181.         return r;
  182.     }
  183.     else {
  184.         if (dev == AUXDEV && has_bconmap)
  185.             dev = curproc->bconmap;
  186.  
  187.         if (dev == 7 && is_falcon) {
  188.             while (!Bconstat(1))
  189.                 yield();
  190.             return Bconin(1);
  191.         }
  192.         if (dev > 0) {
  193.             while (!BCONSTAT(dev)) {
  194.                 yield();
  195.             }
  196.         }
  197.     }
  198.  
  199.     r = BCONIN(dev);
  200.  
  201.     return r;
  202. }
  203.  
  204. /* bconout: output a character.
  205.  * returns 0 for failure, nonzero for success
  206.  */
  207.  
  208. long ARGS_ON_STACK
  209. ubconout(dev, c)
  210. int dev, c;
  211. {
  212.     FILEPTR *f;
  213.     char outp;
  214.  
  215.     if (dev < MAX_BHANDLE) {
  216.         f = curproc->handle[boutput[dev]];
  217.         if (!f) return 0;
  218.         if (is_terminal(f)) {
  219.             return tty_putchar(f, ((long)c)&0x00ff, RAW);
  220.         }
  221.         outp = c;
  222.         return (*f->dev->write)(f, &outp, 1L);
  223.     }
  224.     else if (dev == 5) {
  225.         c &= 0x00ff;
  226.         f = curproc->handle[-1];
  227.         if (!f) return 0;
  228.         if (is_terminal(f)) {
  229.             if (c < ' ') {
  230.             /* MW hack for quoted characters */
  231.                 tty_putchar(f, (long)'\033', RAW);
  232.                 tty_putchar(f, (long)'Q', RAW);
  233.             }
  234.             return tty_putchar(f, ((long)c)&0x00ff, RAW);
  235.         }
  236.     /* note: we're assuming sizeof(int) == 2 here! */
  237.         outp = c;
  238.         return (*f->dev->write)(f, &outp, 1L);
  239.     } else
  240.         return bconout(dev, c);
  241. }
  242.  
  243. long
  244. bconout(dev, c)
  245. int dev,c;
  246. {
  247.     int statdev;
  248.     long endtime;
  249. #define curtime *((unsigned long *)0x4baL)
  250.  
  251.     if (dev == AUXDEV && has_bconmap) {
  252.         dev = curproc->bconmap;
  253.     }
  254.  
  255. /* compensate for a known BIOS bug; MIDI and IKBD are switched */
  256.     if (dev == 3) {        /* MIDI */
  257.         statdev = 4;
  258.     } else if (dev == 4) {
  259.         statdev = 3;
  260.     } else if (dev == 7 && is_falcon) {
  261. /* Falcon BIOS bug */
  262.         (void)Bconout(1,c);
  263.         return 1;
  264.     } else {
  265.         statdev = dev;
  266.     }
  267.  
  268. /* provide a 10 second time out */
  269.     if (!BCOSTAT(statdev)) {
  270.         endtime = curtime + 10*200L;
  271.         do {
  272. #if 0
  273.             yield();
  274. #endif
  275.         } while (!BCOSTAT(statdev) && curtime < endtime);
  276.         if ( curtime >= endtime) return 0;
  277.     }
  278.  
  279. /* special case: many text accelerators return a bad value from
  280.  * Bconout, so we ignore the returned value for the console
  281.  */
  282.     if (dev != CONSDEV) {
  283. /* NOTE: if your compiler complains about the next line, then Bconout is
  284.  * improperly declared in your osbind.h header file. it should be returning
  285.  * a long value; some libraries incorrectly have Bconout returning void
  286.  * (or cast the returned value to void)
  287.  */
  288.         return BCONOUT(dev,c);
  289.     } else {
  290.         (void)BCONOUT(dev, c);
  291.         return 1;
  292.     }
  293. }
  294.  
  295. /* rwabs: various disk stuff */
  296.  
  297. /* BUG: Rwabs should respect Dlock */
  298.  
  299. long ARGS_ON_STACK
  300. rwabs(rwflag, buffer, number, recno, dev, lrecno)
  301. int rwflag, number, recno, dev;
  302. void *buffer;
  303. long lrecno;
  304. {
  305.     long r;
  306.     extern PROC *dlockproc[];    /* in dosdir.c */
  307.  
  308.     if (dev >= 0 && dev < NUM_DRIVES && dlockproc[dev]) {
  309.         if (dlockproc[dev] != curproc) {
  310.             DEBUG(("Rwabs: device %c is locked", dev+'A'));
  311.             return ELOCKED;
  312.         }
  313.     }
  314.  
  315. /* Note that some (most?) Rwabs device drivers don't bother saving
  316.  * registers, whereas our compiler expects politeness. So we go
  317.  * via callout(), which will save registers for us.
  318.  */
  319.     r = callout(RWABS, rwflag, buffer, number, recno, dev, lrecno);
  320.     return r;
  321. }
  322.  
  323. /* setexc: set exception vector */
  324.  
  325. long ARGS_ON_STACK
  326. setexc(number, vector)
  327. int number;
  328. long vector;
  329. {
  330.     long *place;
  331.     long old;
  332.     extern long save_dos, save_bios, save_xbios;    /* in main.c */
  333.     extern int no_mem_prot;                /* in main.c */
  334.  
  335.     place = (long *)(((long)number) << 2);
  336.     if (number == 0x21)                /* trap_1 */
  337.         old = save_dos;
  338.     else if (number == 0x2d)            /* trap_13 */
  339.         old = save_bios;
  340.     else if (number == 0x2e)            /* trap_14 */
  341.         old = save_xbios;
  342.     else if (number == 0x101)
  343.         old = (long)curproc->criticerr;        /* critical error vector */
  344.     else if (number == 0x102)
  345.         old = curproc->ctxt[SYSCALL].term_vec;    /* GEMDOS term vector */
  346.     else
  347.         old = *place;
  348.  
  349.     if (vector > 0) {
  350.     /* validate vector; this will cau